Extract Apical progenitors and compute Pseudo-DorsoVentral score

Extract apical progenitors and filter the gene expression matrix

We perform Kmeans clustering on the 2 cell state scores :

  • Apical progenitors AP
  • Basal progenitors BP

We then extract the glutamatergic neuron branche as beeing the Kmeans cluster with the highest mean Apical progenitor signature

Import Spring dimensionality reduction

Cell cycle associated genes were excluded for PCA dimensionality reduction and Spring plot was generating with these parameter :

Number of cells: 1648
Number of genes that passed filter: 857
Min expressing cells (gene filtering): 3
Min number of UMIs (gene filtering): 3
Gene variability %ile (gene filtering): 90
Number of principal components: 7
Number of nearest neighbors: 20
Number of force layout iterations: 500

Fit a principal curve over the AP in the Spring space

## Starting curve---distance^2: 2022449778
## Iteration 1---distance^2: 745172
## Iteration 2---distance^2: 696270.5
## Iteration 3---distance^2: 677509.1
## Iteration 4---distance^2: 668251.7
## Iteration 5---distance^2: 663393.6
## Iteration 6---distance^2: 660928.6
## Iteration 7---distance^2: 659586.4
## Iteration 8---distance^2: 658917.8
## Iteration 9---distance^2: 658638.8

Manuscript Fig. 5A

Manuscript Fig. 5A

Find differentially expressed genes along the pseudo DV axis

Cluster cell by similar expression profiles on the pseudo-DV axis

Assign domain identity

We assign domain identity based on clusters’ transcriptional profile by setting boundaries over pseudo-dv score

Manuscript Fig. 5D

Manuscript Fig. 5D

Transfert these ident on the full dataset (Manuscript Fig. 2A)

## [1] "Cluster_Sub.Pallium.2: 363 Cells"
## [1] "Cluster_Ventral.Pallium: 312 Cells"
## [1] "Cluster_Sub.Pallium.3: 197 Cells"
## [1] "Cluster_lateral.Pallium.1: 219 Cells"
## [1] "Cluster_Dorsal.Pallium: 201 Cells"
## [1] "Cluster_lateral.Pallium.2: 113 Cells"
## [1] "Cluster_Sub.Pallium.1: 241 Cells"
Manuscript Fig. 2A

Manuscript Fig. 2A

Session Info

## [1] "30 octobre, 2020, 18,19"
## R version 3.6.3 (2020-02-29)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 18.04.5 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/x86_64-linux-gnu/atlas/libblas.so.3.10.3
## LAPACK: /usr/lib/x86_64-linux-gnu/atlas/liblapack.so.3.10.3
## 
## locale:
##  [1] LC_CTYPE=fr_FR.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=fr_FR.UTF-8        LC_COLLATE=fr_FR.UTF-8    
##  [5] LC_MONETARY=fr_FR.UTF-8    LC_MESSAGES=fr_FR.UTF-8   
##  [7] LC_PAPER=fr_FR.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=fr_FR.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
##  [1] splines   stats4    parallel  stats     graphics  grDevices utils    
##  [8] datasets  methods   base     
## 
## other attached packages:
##  [1] viridis_0.5.1       viridisLite_0.3.0   wesanderson_0.3.6  
##  [4] RColorBrewer_1.1-2  gridExtra_2.3       reshape_0.8.8      
##  [7] dplyr_0.8.3         ggExtra_0.9         cluster_2.1.0      
## [10] princurve_2.1.4     monocle_2.14.0      DDRTree_0.1.5      
## [13] irlba_2.3.3         VGAM_1.1-2          Biobase_2.46.0     
## [16] BiocGenerics_0.32.0 Seurat_2.3.4        Matrix_1.2-17      
## [19] cowplot_1.0.0       ggplot2_3.2.1      
## 
## loaded via a namespace (and not attached):
##   [1] snow_0.4-3           backports_1.1.5      Hmisc_4.3-0         
##   [4] plyr_1.8.4           igraph_1.2.5         lazyeval_0.2.2      
##   [7] densityClust_0.3     fastICA_1.2-2        digest_0.6.25       
##  [10] foreach_1.4.7        htmltools_0.5.0      lars_1.2            
##  [13] gdata_2.18.0         magrittr_1.5         checkmate_1.9.4     
##  [16] mixtools_1.1.0       ROCR_1.0-7           limma_3.42.0        
##  [19] matrixStats_0.55.0   R.utils_2.9.0        docopt_0.6.1        
##  [22] colorspace_1.4-1     ggrepel_0.8.1        xfun_0.18           
##  [25] sparsesvd_0.2        crayon_1.3.4         jsonlite_1.7.0      
##  [28] zeallot_0.1.0        survival_2.44-1.1    zoo_1.8-6           
##  [31] iterators_1.0.12     ape_5.3              glue_1.4.1          
##  [34] gtable_0.3.0         kernlab_0.9-29       prabclus_2.3-1      
##  [37] DEoptimR_1.0-8       scales_1.1.0         pheatmap_1.0.12     
##  [40] bibtex_0.4.2         miniUI_0.1.1.1       Rcpp_1.0.5          
##  [43] metap_1.1            dtw_1.21-3           xtable_1.8-4        
##  [46] htmlTable_1.13.2     reticulate_1.13      foreign_0.8-72      
##  [49] bit_4.0.4            proxy_0.4-23         mclust_5.4.5        
##  [52] SDMTools_1.1-221.1   Formula_1.2-3        tsne_0.1-3          
##  [55] htmlwidgets_1.5.1    httr_1.4.1           FNN_1.1.3           
##  [58] gplots_3.0.1.1       fpc_2.2-3            acepack_1.4.1       
##  [61] modeltools_0.2-22    ica_1.0-2            farver_2.0.1        
##  [64] pkgconfig_2.0.3      R.methodsS3_1.7.1    flexmix_2.3-15      
##  [67] nnet_7.3-14          labeling_0.3         tidyselect_0.2.5    
##  [70] rlang_0.4.7          reshape2_1.4.3       later_1.0.0         
##  [73] munsell_0.5.0        tools_3.6.3          ggridges_0.5.1      
##  [76] fastmap_1.0.1        evaluate_0.14        stringr_1.4.0       
##  [79] yaml_2.2.1           npsurv_0.4-0         knitr_1.26          
##  [82] bit64_4.0.2          fitdistrplus_1.0-14  robustbase_0.93-5   
##  [85] caTools_1.17.1.2     purrr_0.3.3          RANN_2.6.1          
##  [88] pbapply_1.4-2        nlme_3.1-141         mime_0.7            
##  [91] slam_0.1-46          R.oo_1.23.0          hdf5r_1.3.2.9000    
##  [94] compiler_3.6.3       rstudioapi_0.11      png_0.1-7           
##  [97] lsei_1.2-0           tibble_2.1.3         stringi_1.4.6       
## [100] highr_0.8            lattice_0.20-41      HSMMSingleCell_1.6.0
## [103] vctrs_0.2.0          pillar_1.4.2         lifecycle_0.1.0     
## [106] combinat_0.0-8       Rdpack_0.11-0        lmtest_0.9-37       
## [109] data.table_1.12.6    bitops_1.0-6         gbRd_0.4-11         
## [112] httpuv_1.5.2         R6_2.4.1             latticeExtra_0.6-28 
## [115] promises_1.1.0       KernSmooth_2.23-15   codetools_0.2-16    
## [118] MASS_7.3-53          gtools_3.8.1         assertthat_0.2.1    
## [121] withr_2.1.2          qlcMatrix_0.9.7      mgcv_1.8-33         
## [124] diptest_0.75-7       doSNOW_1.0.18        grid_3.6.3          
## [127] rpart_4.1-15         tidyr_1.0.0          class_7.3-17        
## [130] rmarkdown_2.5        segmented_1.0-0      Rtsne_0.15          
## [133] shiny_1.4.0          base64enc_0.1-3

  1. Institute of Psychiatry and Neuroscience of Paris, INSERM U1266, 75014, Paris, France

LS0tCnRpdGxlOiAiSW52ZXN0aWdhdGlvbiBvZiB0aGUgYXBpY2FsIHByb2dlbml0b3JzIGRpdmVyc2l0eSIKYXV0aG9yOgogIC0gTWF0dGhpZXUgTW9yZWF1XltJbnN0aXR1dGUgb2YgUHN5Y2hpYXRyeSBhbmQgTmV1cm9zY2llbmNlIG9mIFBhcmlzLCBJTlNFUk0gVTEyNjYsIDc1MDE0LCBQYXJpcywgRnJhbmNlXSwgbWF0dGhpZXUubW9yZWF1QGluc2VybS5mcgpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiwgJVknKWAiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDogCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMKICAgIGRmX3ByaW50OiB0aWJibGUKICAgIGhpZ2hsaWdodDogaGFkZG9jawogICAgaW5jbHVkZXM6CiAgICAgIGluX2hlYWRlcjogaGVhZGVyLmh0bWwKICAgIHRoZW1lOiBjb3NtbwogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogNQogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IHllcwotLS0KCmBgYHtjc3MsIGVjaG89RkFMU0V9CmgxIHsKICBmb250LXNpemU6IDM0cHg7CiAgbWFyZ2luLXRvcDogMnJlbTsKICBtYXJnaW4tYm90dG9tOiAxcmVtOwogIGNvbG9yOiAjZTY0ZDAwOwogIHRleHQtZGVjb3JhdGlvbjogbm9uZTsKfQpoMS50aXRsZSB7CiAgZm9udC1zaXplOiA0MHB4OwogIG1hcmdpbi10b3A6IDJyZW07CiAgbWFyZ2luLWJvdHRvbTogMXJlbTsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgdGV4dC1kZWNvcmF0aW9uOiBub25lOwogIGNvbG9yOiAjMDAwMDAwOwp9CmgyIHsKICBmb250LXNpemU6IDMwcHg7CiAgbWFyZ2luLXRvcDogMnJlbTsKICBtYXJnaW4tYm90dG9tOiAxcmVtOwogIGNvbG9yOiAjMDAwMDAwOwp9CmgzIHsKICBmb250LXNpemU6IDI0cHg7CiAgbWFyZ2luLXRvcDogMnJlbTsKICBtYXJnaW4tYm90dG9tOiAxcmVtOwogIGNvbG9yOiAjMDAwMDAwOwp9Cmg0IHsKICBmb250LXNpemU6IDIwcHg7CiAgbWFyZ2luLXRvcDogMnJlbTsKICBtYXJnaW4tYm90dG9tOiAxcmVtOwogIGNvbG9yOiAjMDAwMDAwOwp9Cmg1IHsKICBmb250LXNpemU6IDE4cHg7CiAgbWFyZ2luLXRvcDogMnJlbTsKICBtYXJnaW4tYm90dG9tOiAxcmVtOwogIGNvbG9yOiAjMDAwMDAwOwp9Cgouc2Nyb2xsLTEwMCB7CiAgbWF4LWhlaWdodDogMjAwcHg7CiAgb3ZlcmZsb3cteTogYXV0bzsKICBiYWNrZ3JvdW5kLWNvbG9yOiBpbmhlcml0Owp9CgpwIHsKICBmb250LXNpemU6IDE2cHg7Cn0KYGBgCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCBmaWcuYWxpZ24gPSAnY2VudGVyJywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSkKYGBgCgojIExvYWQgbGlicmFyaWVzIGFuZCBRQ0ZpbHRlcmVkIGRhdGFzZXQKCmBgYHtyIH0KIyBMb2FkIGxpYnJhcnkKbGlicmFyeShTZXVyYXQpCmxpYnJhcnkobW9ub2NsZSkKbGlicmFyeShwcmluY3VydmUpCmxpYnJhcnkoY2x1c3RlcikKbGlicmFyeShwYXJhbGxlbCkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdnRXh0cmEpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkocmVzaGFwZSkKbGlicmFyeShncmlkRXh0cmEpCmxpYnJhcnkoUkNvbG9yQnJld2VyKQpsaWJyYXJ5KHdlc2FuZGVyc29uKQpsaWJyYXJ5KHZpcmlkaXMpCgojU2V0IGdncGxvdCB0aGVtZSBhcyBjbGFzc2ljCnRoZW1lX3NldCh0aGVtZV9jbGFzc2ljKCkpCmBgYAoKYGBge3J9CiMgTG9hZCB0aGUgZnVsbCBhbm5vdGF0ZWQgZGF0YXNldApBbGxjZWxscy5kYXRhIDwtIHJlYWRSRFMoIi4vUUMuZmlsdGVyZWQuY2VsbHMuUkRTIikKYGBgCgojIEV4dHJhY3QgQXBpY2FsIHByb2dlbml0b3JzIGFuZCBjb21wdXRlIFBzZXVkby1Eb3Jzb1ZlbnRyYWwgc2NvcmUKCiMjIEV4dHJhY3QgYXBpY2FsIHByb2dlbml0b3JzIGFuZCBmaWx0ZXIgdGhlIGdlbmUgZXhwcmVzc2lvbiBtYXRyaXgKCldlIHBlcmZvcm0gS21lYW5zIGNsdXN0ZXJpbmcgb24gdGhlIDIgY2VsbCBzdGF0ZSBzY29yZXMgOgoKLSBBcGljYWwgcHJvZ2VuaXRvcnMgYEFQYAotIEJhc2FsIHByb2dlbml0b3JzIGBCUGAKCmBgYHtyIH0Kc2V0LnNlZWQoMTAwKQojSy1tZWFucyBjbHVzdGVyaW5nIGJhc2VkIG9uIEFQLCBCUCBzY29yZXMgYWNyb3NzIGNlbGxzCmNsIDwtIGttZWFucyhjYmluZChBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSRBUF9zaWduYXR1cmUxLCBBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSRCUF9zaWduYXR1cmUxKSwgMykKQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEka21lYW5DbHVzdCA8LSBwYXN0ZTAoIkNsdXN0LiIsY2wkY2x1c3RlcikKYGBgCgoKYGBge3IgZmlnLmRpbT1jKDUuMywgNCl9CmNvbC5wYWwgPC0gd2VzX3BhbGV0dGUoIkdyYW5kQnVkYXBlc3QxIiwgMywgdHlwZSA9ICJkaXNjcmV0ZSIpCgpwMSA8LSBnZ3Bsb3QoQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEsIGFlcyh4PUFQX3NpZ25hdHVyZTEsIHk9QlBfc2lnbmF0dXJlMSwgY29sb3VyID0ga21lYW5DbHVzdCkpICsKICBnZW9tX3BvaW50KHZhbHVlcz1jb2wucGFsKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmdnTWFyZ2luYWwocDEsIHR5cGUgPSAiaGlzdG9ncmFtIiwgZmlsbD0ibGlnaHRncmV5IikgOyBybShwMSkKCkRpbVBsb3QoQWxsY2VsbHMuZGF0YSwKICAgICAgICBncm91cC5ieSA9ICJrbWVhbkNsdXN0IiwKICAgICAgICByZWR1Y3Rpb24udXNlID0gInNwcmluZyIsCiAgICAgICAgY29scy51c2UgPSBjb2wucGFsLAogICAgICAgIGRpbS4xID0gMSwKICAgICAgICBkaW0uMiA9IDIsCiAgICAgICAgZG8ubGFiZWw9VCwKICAgICAgICBsYWJlbC5zaXplID0gNCwKICAgICAgICBuby5sZWdlbmQgPSBGKQpgYGAKCldlIHRoZW4gZXh0cmFjdCB0aGUgZ2x1dGFtYXRlcmdpYyBuZXVyb24gYnJhbmNoZSBhcyBiZWVpbmcgdGhlIEttZWFucyBjbHVzdGVyIHdpdGggdGhlIGhpZ2hlc3QgbWVhbiBgQXBpY2FsIHByb2dlbml0b3JgIHNpZ25hdHVyZQoKYGBge3IgZmlnLmRpbT1jKDUuMywgNCl9CiNGaW4gY2x1c3RlciB3aWh0IHRoZSBoaWdoZXN0IG1lYW4gQVBzY29yZQpNZWFuS2NsdXN0LkFQc2NvcmUgPC0gYWdncmVnYXRlKEFQX3NpZ25hdHVyZTEgfiBrbWVhbkNsdXN0LCBBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSwgbWVhbikKQVBjbHVzdCA8LSBNZWFuS2NsdXN0LkFQc2NvcmUgJT4lIGZpbHRlcihBUF9zaWduYXR1cmUxID09IG1heChBUF9zaWduYXR1cmUxKSkgJT4lIHB1bGwoa21lYW5DbHVzdCkKCiNFeHRyYWN0IGFwaWNhbCBwcm9nZW5pdG9ycyAKYmFyY29kZXMgPC0gQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEgJT4lIGZpbHRlcihrbWVhbkNsdXN0ID09IEFQY2x1c3QpICU+JSBwdWxsKEJhcmNvZGVzKQpBUC5kYXRhIDwtICBTdWJzZXREYXRhKEFsbGNlbGxzLmRhdGEsIGNlbGxzLnVzZSA9IGJhcmNvZGVzICwgc3Vic2V0LnJhdyA9IFQsICBkby5jbGVhbiA9IEYpCgojRnVydGhlciBmaWx0ZXIgdGhlIDMgb3V0bGllciBjZWxscyBiYXNlZCBvbiBzcHJpbmcgY29vcmRpbmF0ZXMKY2VsbHMgPC0gcm93bmFtZXMoQVAuZGF0YUBkciRzcHJpbmdAY2VsbC5lbWJlZGRpbmdzW0FQLmRhdGFAZHIkc3ByaW5nQGNlbGwuZW1iZWRkaW5nc1ssMl0gPiAyNTAsXSkKQVAuZGF0YSA8LSAgU3Vic2V0RGF0YShBUC5kYXRhLCBjZWxscy51c2UgPSBjZWxscyAsIHN1YnNldC5yYXcgPSBULCAgZG8uY2xlYW4gPSBGKQoKRGltUGxvdChBUC5kYXRhLAogICAgICAgIGdyb3VwLmJ5ID0gImttZWFuQ2x1c3QiLAogICAgICAgIHJlZHVjdGlvbi51c2UgPSAic3ByaW5nIiwKICAgICAgICBjb2xzLnVzZSA9IGNvbC5wYWwsCiAgICAgICAgZGltLjEgPSAxLAogICAgICAgIGRpbS4yID0gMiwKICAgICAgICBkby5sYWJlbD1ULAogICAgICAgIGxhYmVsLnNpemUgPSA0LAogICAgICAgIG5vLmxlZ2VuZCA9IEYpCmBgYAoKIyMgRmlsdGVyIGdlbmUgZXhwcmVzc2lvbiBtYXRyaXgKCmBgYHtyfQojUmVtb3ZlIG5vbiBlcHJlc3NlZCBnZW5lcwpudW0uY2VsbHMgPC0gTWF0cml4Ojpyb3dTdW1zKEFQLmRhdGFAZGF0YSA+IDApCmdlbmVzLnVzZSA8LSBuYW1lcyh4ID0gbnVtLmNlbGxzW3doaWNoKHggPSBudW0uY2VsbHMgPj0gMjApXSkKQVAuZGF0YUByYXcuZGF0YSA8LSBBUC5kYXRhQHJhdy5kYXRhW2dlbmVzLnVzZSwgXQpBUC5kYXRhQGRhdGEgPC0gQVAuZGF0YUBkYXRhW2dlbmVzLnVzZSwgXQoKI05vcm1hbGl6ZSBhbmQgU2NhbGUgdGhlIGRhdGEKQVAuZGF0YSA8LSBOb3JtYWxpemVEYXRhKG9iamVjdCA9IEFQLmRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICBub3JtYWxpemF0aW9uLm1ldGhvZCA9ICJMb2dOb3JtYWxpemUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlLmZhY3RvciA9IHJvdW5kKG1lZGlhbihBUC5kYXRhQG1ldGEuZGF0YSRuVU1JKSksCiAgICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5LnByb2dyZXNzID0gRikKCkFQLmRhdGEgPC0gRmluZFZhcmlhYmxlR2VuZXMob2JqZWN0ID0gQVAuZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW4uZnVuY3Rpb24gPSBFeHBNZWFuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGVyc2lvbi5mdW5jdGlvbiA9IExvZ1ZNUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHgubG93LmN1dG9mZiA9IDAuMDEyNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHguaGlnaC5jdXRvZmYgPSAzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeS5jdXRvZmYgPSAxLCBkby5wbG90ID0gRiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXkucHJvZ3Jlc3MgPSBGKQoKQVAuZGF0YSA8LSBTY2FsZURhdGEob2JqZWN0ID0gQVAuZGF0YSwgdmFycy50by5yZWdyZXNzID0gYygiQ0MuRGlmZmVyZW5jZSIsInBlcmNlbnQubWl0byIsICJuVU1JIiksIGRpc3BsYXkucHJvZ3Jlc3MgPSBGKQpgYGAKCiMjIEltcG9ydCBTcHJpbmcgZGltZW5zaW9uYWxpdHkgcmVkdWN0aW9uCgoqKkNlbGwgY3ljbGUgYXNzb2NpYXRlZCBnZW5lcyoqIHdlcmUgZXhjbHVkZWQgZm9yIFBDQSBkaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24gYW5kIFNwcmluZyBwbG90IHdhcyBnZW5lcmF0aW5nIHdpdGggdGhlc2UgcGFyYW1ldGVyIDoKCmBgYApOdW1iZXIgb2YgY2VsbHM6IDE2NDgKTnVtYmVyIG9mIGdlbmVzIHRoYXQgcGFzc2VkIGZpbHRlcjogODU3Ck1pbiBleHByZXNzaW5nIGNlbGxzIChnZW5lIGZpbHRlcmluZyk6IDMKTWluIG51bWJlciBvZiBVTUlzIChnZW5lIGZpbHRlcmluZyk6IDMKR2VuZSB2YXJpYWJpbGl0eSAlaWxlIChnZW5lIGZpbHRlcmluZyk6IDkwCk51bWJlciBvZiBwcmluY2lwYWwgY29tcG9uZW50czogNwpOdW1iZXIgb2YgbmVhcmVzdCBuZWlnaGJvcnM6IDIwCk51bWJlciBvZiBmb3JjZSBsYXlvdXQgaXRlcmF0aW9uczogNTAwCmBgYAoKYGBge3IgZmlnLmRpbT1jKDUuMywgNCl9CiNJbXBvcnQgU3ByaW5nIGNvb3JkaW5hdGVzIGNhbGN1bGF0ZWQgd2l0aG91dCBjZWxsIGN5Y2xlIGdlbmVzCkNvb3JkaW5hdGVzIDwtIHJlYWQudGFibGUoIi4vUHJvZ2VuaXRvcnMvRTEyLkFQLkNvb3JkaW5hdGVzLnR4dCIsIHNlcD0iLCIsIGhlYWRlciA9IEYpWyxjKDIsMyldCnJvd25hbWVzKENvb3JkaW5hdGVzKSA8LSByb3duYW1lcyhBUC5kYXRhQG1ldGEuZGF0YSkKQVAuZGF0YSA8LSBTZXREaW1SZWR1Y3Rpb24oQVAuZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVkdWN0aW9uLnR5cGUgPSAic3ByaW5nLkFQIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2xvdCA9ICJjZWxsLmVtYmVkZGluZ3MiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcuZGF0YSA9IGFzLm1hdHJpeChDb29yZGluYXRlcykpCkFQLmRhdGFAZHIkc3ByaW5nLkFQQGtleSA8LSAic3ByaW5nLkFQIgpjb2xuYW1lcyhBUC5kYXRhQGRyJHNwcmluZy5BUEBjZWxsLmVtYmVkZGluZ3MpIDwtIHBhc3RlMChHZXREaW1SZWR1Y3Rpb24ob2JqZWN0ID0gQVAuZGF0YSwgcmVkdWN0aW9uLnR5cGUgPSAic3ByaW5nLkFQIixzbG90ID0gImtleSIpLCBjKDEsMikpCgoKRGltUGxvdChBUC5kYXRhLAogICAgICAgIHJlZHVjdGlvbi51c2UgPSAic3ByaW5nLkFQIiwKICAgICAgICBncm91cC5ieSA9ICJQaGFzZSIsCiAgICAgICAgY29scy51c2UgPSBjb2wucGFsLAogICAgICAgIGRpbS4xID0gMSwgCiAgICAgICAgZGltLjIgPSAyLAogICAgICAgIGRvLmxhYmVsPVQsCiAgICAgICAgbGFiZWwuc2l6ZSA9IDQsCiAgICAgICAgbm8ubGVnZW5kID0gRiApCmBgYAoKIyMgRml0IGEgcHJpbmNpcGFsIGN1cnZlIG92ZXIgdGhlIEFQIGluIHRoZSBTcHJpbmcgc3BhY2UKCmBgYHtyfQpkYXRhIDwtIGRhdGEuZnJhbWUoc3ByaW5nQVAuMSA9IEFQLmRhdGFAZHIkc3ByaW5nLkFQQGNlbGwuZW1iZWRkaW5nc1ssMV0sCiAgICAgICAgICAgICAgICAgICBzcHJpbmdBUC4yID0gQVAuZGF0YUBkciRzcHJpbmcuQVBAY2VsbC5lbWJlZGRpbmdzWywyXSwKICAgICAgICAgICAgICAgICAgIHNwcmluZzEgPSBBUC5kYXRhQGRyJHNwcmluZ0BjZWxsLmVtYmVkZGluZ3NbLDFdLAogICAgICAgICAgICAgICAgICAgc3ByaW5nMiA9IEFQLmRhdGFAZHIkc3ByaW5nQGNlbGwuZW1iZWRkaW5nc1ssMl0pCgojIEZpdCB0aGUgcHJpbmNpcGFsIGN1cnZlCmZpdCA8LSBwcmluY2lwYWxfY3VydmUoYXMubWF0cml4KGRhdGFbLDE6Ml0pLAogICAgICAgICAgICAgICAgICAgICAgIHNtb290aGVyPSdsb3dlc3MnLAogICAgICAgICAgICAgICAgICAgICAgIHRyYWNlPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgZiA9IDAuNywKICAgICAgICAgICAgICAgICAgICAgICBzdHJldGNoPTAsCiAgICAgICAgICAgICAgICAgICAgICAgcGxvdF9pdGVyYXRpb25zID0gRikKYGBgCgpgYGB7cn0KRG9yc29WZW50cmFsLlNjb3JlIDwtIGZpdCRsYW1iZGEvbWF4KGZpdCRsYW1iZGEpICNUaGUgYWN0dWFsIHNwZXVkb3RpbWUKcGMubGluZSA8LSBhcy5kYXRhLmZyYW1lKGZpdCRzW29yZGVyKGZpdCRsYW1iZGEpLF0pICNUaGUgcHJpbmNpcGFsIGN1cnZlIHNtb290aGVkCgpkYXRhJFBoYXNlIDwtIGFzLmNoYXJhY3RlcihBUC5kYXRhQG1ldGEuZGF0YSRQaGFzZSkKZGF0YSREb3Jzb1ZlbnRyYWwuU2NvcmUgPC0gRG9yc29WZW50cmFsLlNjb3JlCgojIERpcmVjdGlvbiBvZiB0aGUgbWF0dXJhdGlvbiBzY29yZSB1c2luZyBaYnRiMjAgZXhwcmVzc2lvbiAocmV2ZXJ0ZSBpZiBwb3NpdGl2ZSBjb3JyZWxhdGlvbikKaWYgKGNvcihkYXRhJERvcnNvVmVudHJhbC5TY29yZSwgQVAuZGF0YUBkYXRhWydaYnRiMjAnLCBdKSA+IDApIHsgZGF0YSREb3Jzb1ZlbnRyYWwuU2NvcmUgPC0gLShkYXRhJERvcnNvVmVudHJhbC5TY29yZSAtIG1heChkYXRhJERvcnNvVmVudHJhbC5TY29yZSkpfQoKQVAuZGF0YUBtZXRhLmRhdGEkRG9yc29WZW50cmFsLlNjb3JlIDwtIGRhdGEkRG9yc29WZW50cmFsLlNjb3JlCmBgYAoKYGBge3IgZmlnLmRpbT1jKDUuMywgNCl9CiNQbG90IENlbGwgb250byBQQzEgYW5kIFBDMiB3aXRoIHByaW5jaXBhbCBjdXJ2ZQpnZ3Bsb3QoZGF0YSwgYWVzKHNwcmluZ0FQLjEsIHNwcmluZ0FQLjIpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVBoYXNlKSwgc2l6ZT0yLCBzaGFwZT0xNiwgdmFsdWVzPWNvbC5wYWwpICsKICBnZW9tX2xpbmUoZGF0YT1wYy5saW5lLCBjb2xvcj0ncmVkJywgc2l6ZT0wLjc3KQpgYGAKCmBgYHtyIGZpZy5kaW09Yyg1LjMsIDQpLCBmaWcuY2FwPSAiTWFudXNjcmlwdCBGaWcuIDVBIn0KI1Bsb3QgU3BldWRvdGltZSBjb2xvciBncmFkaWVudCBvbiB0aGUgY2VsbCBjeWNsZSBmaWx0ZXJlZCBTcHJpbmcgZW1iYmVkaW5nCmdncGxvdChkYXRhLCBhZXMoc3ByaW5nQVAuMSwgc3ByaW5nQVAuMikpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1Eb3Jzb1ZlbnRyYWwuU2NvcmUpLCBzaXplPTIsIHNoYXBlPTE2KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpcygpICsKICBnZW9tX2xpbmUoZGF0YT1wYy5saW5lLCBjb2xvcj0ncmVkJywgc2l6ZT0wLjc3KQpgYGAKCmBgYHtyIGZpZy5kaW09Yyg1LjMsIDQpfQojUGxvdCBTcGV1ZG90aW1lIGNvbG9yIGdyYWRpZW50IG9uIHRoZSBTcHJpbmcgZW1iYmVkaW5nIGNhbGN1bGF0ZWQgZnJvbSBmdWxsIGRhdGFzZXQKZ2dwbG90KGRhdGEsIGFlcyhzcHJpbmcxLCBzcHJpbmcyKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1Eb3Jzb1ZlbnRyYWwuU2NvcmUpLCBzaXplPTIsIHNoYXBlPTE2KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpcygpIApgYGAKCiMgRmluZCBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMgYWxvbmcgdGhlIHBzZXVkbyBEViBheGlzCgojIyBJbml0aWFsaXplIGEgbW9ub2NsZSBvYmplY3QKCmBgYHtyfQojIFRyYW5zZmVydCBtZXRhZGF0YSAKbWV0YS5kYXRhIDwtIGRhdGEuZnJhbWUoYmFyY29kZSA9IHJvd25hbWVzKEFQLmRhdGFAbWV0YS5kYXRhKSwKICAgICAgICAgICAgICAgICAgICAgICAgQ2x1c3RlciA9IEFQLmRhdGFAbWV0YS5kYXRhJG9sZC5pZGVudCwKICAgICAgICAgICAgICAgICAgICAgICAgRG9yc29WZW50cmFsLlNjb3JlID0gIEFQLmRhdGFAbWV0YS5kYXRhJERvcnNvVmVudHJhbC5TY29yZSwKICAgICAgICAgICAgICAgICAgICAgICAgQ2VsbGN5Y2xlUGhhc2UgPSBBUC5kYXRhQG1ldGEuZGF0YSRQaGFzZSwKICAgICAgICAgICAgICAgICAgICAgICAgcm93Lm5hbWVzID0gcm93bmFtZXMoQVAuZGF0YUBtZXRhLmRhdGEpKQogICAgICAgICAgICAgICAgICAgCkFubm90LmRhdGEgIDwtIG5ldygnQW5ub3RhdGVkRGF0YUZyYW1lJywgZGF0YSA9IG1ldGEuZGF0YSkKCiMgVHJhbnNmZXJ0IGNvdW50IGRhdGEKY291bnQuZGF0YSA9IGRhdGEuZnJhbWUoZ2VuZV9zaG9ydF9uYW1lID0gcm93bmFtZXMoQVAuZGF0YUByYXcuZGF0YSksCiAgICAgICAgICAgICAgICAgIHJvdy5uYW1lcyA9IHJvd25hbWVzKEFQLmRhdGFAcmF3LmRhdGEpKQoKZmVhdHVyZS5kYXRhIDwtIG5ldygnQW5ub3RhdGVkRGF0YUZyYW1lJywgZGF0YSA9IGNvdW50LmRhdGEpCgojIENyZWF0ZSB0aGUgQ2VsbERhdGFTZXQgb2JqZWN0CmdibV9jZHMgPC0gbmV3Q2VsbERhdGFTZXQoYXMubWF0cml4KEFQLmRhdGFAcmF3LmRhdGEpLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBoZW5vRGF0YSA9IEFubm90LmRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZmVhdHVyZURhdGEgPSBmZWF0dXJlLmRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbG93ZXJEZXRlY3Rpb25MaW1pdCA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbkZhbWlseSA9IG5lZ2Jpbm9taWFsKCkpCmBgYAoKCmBgYHtyfQpnYm1fY2RzIDwtIGVzdGltYXRlU2l6ZUZhY3RvcnMoZ2JtX2NkcykKZ2JtX2NkcyA8LSBlc3RpbWF0ZURpc3BlcnNpb25zKGdibV9jZHMpCmdibV9jZHMgPC0gZGV0ZWN0R2VuZXMoZ2JtX2NkcywgbWluX2V4cHIgPSAwLjEpCmBgYAoKYGBge3J9CnJtKGxpc3QgPSBscygpWyFscygpICVpbiUgYygiQVAuZGF0YSIsICJnYm1fY2RzIildKQpgYGAKCiMjIFRlc3QgZWFjaCBnZW5lIHRyZW5kIG92ZXIgcHNldWRvLURWIHNjb3JlCgpgYGB7cn0KIyBFeGNsdWRlIGNlbGwgY3ljbGUgYXNzb2NpYXRlZCBnZW5lcwpDQ2dlbmVzIDwtIGFzLmNoYXJhY3RlcihyZWFkLnRhYmxlKCIuL1Byb2dlbml0b3JzL0NlbGxDeWNsZUdlbmVzLmNzdiIsIHNlcCA9ICJcdCIsIGhlYWRlciA9IEYpWywxXSkKSW5wdXQuZ2VuZXMgPC0gQVAuZGF0YUB2YXIuZ2VuZXNbIUFQLmRhdGFAdmFyLmdlbmVzICVpbiUgQ0NnZW5lc10KYGBgCgoKYGBge3J9CiMgUGVyZm9ybSB0aGUgdGVzdCBmb3IgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gYXMgYSBmdW5jdGlvbiBvZiBwc2V1ZG8tRFYgc2NvcmUgd2hpbGUgY29udHJvbGluZyBmb3IgY2VsbCBjeWNsZSBwaGFzZQpEVi5BeGlzLmdlbmVzIDwtIGRpZmZlcmVudGlhbEdlbmVUZXN0KGdibV9jZHNbSW5wdXQuZ2VuZXMsXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVsbE1vZGVsRm9ybXVsYVN0ciA9ICJ+c20ubnMoRG9yc29WZW50cmFsLlNjb3JlLCBkZiA9IDMpKkNlbGxjeWNsZVBoYXNlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVkdWNlZE1vZGVsRm9ybXVsYVN0ciA9ICJ+Q2VsbGN5Y2xlUGhhc2UiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGRldGVjdENvcmVzKCkgLTIpCgojIEZpbHRlciBnZW5lcyB3aXRoIGEgRkRSIDwgMC4wMDEKRFYuQXhpcy5nZW5lcy5GRFIuZmlsdGVyZWQgPC0gRFYuQXhpcy5nZW5lcyAlPiUgZmlsdGVyKHF2YWwgPCAxZS0zKQpgYGAKCgojIyBTbW9vdGggc2lnbmlmaWNhdGl2ZSBnZW5lIGV4cHJlc3Npb24gcHNldWRvLURWIGF4aXMKCmBgYHtyfQojIENyZWF0ZSBhIG5ldyBwc2V1ZG8tRFYgdmVjdG9yIG9mIDUwMCBwb2ludHMKblBvaW50cyA8LSA1MDAKbmV3X2RhdGEgPC0gZGF0YS5mcmFtZShEb3Jzb1ZlbnRyYWwuU2NvcmUgPSBzZXEobWluKHBEYXRhKGdibV9jZHMpJERvcnNvVmVudHJhbC5TY29yZSksIG1heChwRGF0YShnYm1fY2RzKSREb3Jzb1ZlbnRyYWwuU2NvcmUpLCBsZW5ndGgub3V0ID0gblBvaW50cykpCgojIFNtb290aCBnZW5lIGV4cHJlc3Npb24KU21vb3RoLmN1cnZlLm1hdHJpeCA8LSBnZW5TbW9vdGhDdXJ2ZXMoZ2JtX2Nkc1thcy5jaGFyYWN0ZXIoRFYuQXhpcy5nZW5lcy5GRFIuZmlsdGVyZWQkZ2VuZV9zaG9ydF9uYW1lKSxdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVuZF9mb3JtdWxhID0gIn5zbS5ucyhEb3Jzb1ZlbnRyYWwuU2NvcmUsIGRmID0gMykiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZV9leHByID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3X2RhdGEgPSBuZXdfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZXM9IGRldGVjdENvcmVzKCkgLSAyKQpgYGAKCiMgQ2x1c3RlciBnZW5lIGJ5IHNpbWlsYXIgcHJvZmlsZXMgb3ZlciBwc2V1ZG8tRFYgYXhpcwoKYGBge3J9CnNldC5zZWVkKDEwMCkKIyBDbHVzdGVyIGdlbmVzIHVzaW5nIHRoZSBQYXJ0aXRpb25pbmcgQXJvdW5kIE1lZG9pZHMgYWxnb3JpdGhtCkRWLkF4aXMuZ2VuZXMuY2x1c3RlcnMgPC0gcGFtKGFzLmRpc3QoKDEtY29yKE1hdHJpeDo6dChTbW9vdGguY3VydmUubWF0cml4KSwgbWV0aG9kID0gInNwZWFybWFuIikpKSwgaz05KQp0YWJsZShEVi5BeGlzLmdlbmVzLmNsdXN0ZXJzJGNsdXN0ZXJpbmcpCmBgYAoKYGBge3J9CiMgU3RvcmUgdGhlIHJlc3VsdHMgCkdlbmUuZHluYW1pcXVlIDwtIGRhdGEuZnJhbWUoR2VuZT0gbmFtZXMoRFYuQXhpcy5nZW5lcy5jbHVzdGVycyRjbHVzdGVyaW5nKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdmFsPSBEVi5BeGlzLmdlbmVzLkZEUi5maWx0ZXJlZCRwdmFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF2YWw9RFYuQXhpcy5nZW5lcy5GRFIuZmlsdGVyZWQkcXZhbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1fY2VsbHNfZXhwcmVzc2VkPURWLkF4aXMuZ2VuZXMuRkRSLmZpbHRlcmVkJG51bV9jZWxsc19leHByZXNzZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV2F2ZXMgPSBEVi5BeGlzLmdlbmVzLmNsdXN0ZXJzJGNsdXN0ZXJpbmcpICU+JSBhcnJhbmdlKFdhdmVzKQoKcm93Lm5hbWVzKEdlbmUuZHluYW1pcXVlKSA8LSBHZW5lLmR5bmFtaXF1ZSRHZW5lCkdlbmUuZHluYW1pcXVlJEdlbmUuQ2x1c3RlcnMgPC0gcGFzdGUwKCJDbHVzdC4iLEdlbmUuZHluYW1pcXVlJFdhdmVzKQoKd3JpdGUudGFibGUoR2VuZS5keW5hbWlxdWUsICIuL1Byb2dlbml0b3JzL0dlbmUuZHluYW1pcXVlLmNzdiIsIHNlcCA9ICI7IiwgcXVvdGUgPSBGKQpgYGAKCmBgYHtyfQojIExvYWQgY3VzdG9tIHBsb3R0aW5nIGZ1bmN0aW9ucwpzb3VyY2UoIi4vZnVuY3Rpb25zL0dlbmVzVHJlbmRQbG90cy5SIikKYGBgCgpgYGB7ciBmaWcuZGltPWMoNiwgOSksIGZpZy5jYXA9ICJNYW51c2NyaXB0IEZpZy4gNUMifQojUGxvdCBnZW5lIGNsdXN0ZXJzIHRyZW5kcwpDbHVzdGVycy50cmVuZChBUC5kYXRhLAogICAgICAgICAgICAgICBXaGljaC5jbHVzdGVyID0gMTo5LAogICAgICAgICAgICAgICBjbHVzdC5saXN0ID0gRFYuQXhpcy5nZW5lcy5jbHVzdGVycywKICAgICAgICAgICAgICAgZ3JvdXAuYnkgPSAiZ2xvYmFsIiwKICAgICAgICAgICAgICAgc3BhbiA9IDEsCiAgICAgICAgICAgICAgIFNtb290aC5tZXRob2QgPSAiYXV0byIsCiAgICAgICAgICAgICAgIFVzZS5zY2FsZS5kYXRhID0gVCkKYGBgCgoKIyBDbHVzdGVyIGNlbGwgYnkgc2ltaWxhciBleHByZXNzaW9uIHByb2ZpbGVzIG9uIHRoZSBwc2V1ZG8tRFYgYXhpcwoKYGBge3J9CnNldC5zZWVkKDEwMCkKIyBDbHVzdGVyIGNlbGxzIHVzaW5nIHRoZSBQYXJ0aXRpb25pbmcgQXJvdW5kIE1lZG9pZHMgYWxnb3JpdGhtCkNlbGxzLkNsdXN0IDwtIHBhbShhcy5kaXN0KCgxIC0gY29yKFNtb290aC5jdXJ2ZS5tYXRyaXggLG1ldGhvZCA9ICJzcGVhcm1hbiIpKSksIGs9NykKRG9tYWluZXMuQ2x1c3QgPC0gZGF0YS5mcmFtZShEb21haW5lcyA9IHBhc3RlMCgiQ2x1c3QuIixDZWxscy5DbHVzdCRjbHVzdGVyaW5nKSkKYGBgCgojIyBQbG90IGdlbmUvY2VsbCBoZWF0bWFwCgpgYGB7ciBmaWcuZGltPWMoNywgOS4zKSwgZmlnLmNhcD0gIk1hbnVzY3JpcHQgRmlnLiA1QyJ9CiMgUmUtb3JkZXIgZ2VuZSBleHByZXNzaW9uIGNsdXN0ZXIgYWxvbmcgdGhlIGF4aXMKU29ydGVkLmdlbmUuZHluIDwtIEdlbmUuZHluYW1pcXVlICU+JSBhcnJhbmdlKGZhY3RvcihHZW5lLkNsdXN0ZXJzLCBsZXZlbHMgPSBwYXN0ZTAoIkNsdXN0LiIsYyg3LDIsNiwzLDEsOSw1LDQsOCkpKSkKcm93bmFtZXMoU29ydGVkLmdlbmUuZHluKSA8LSBTb3J0ZWQuZ2VuZS5keW4kR2VuZQoKYW5uby5jb2xvcnMgPC0gbGlzdChEb21haW5lcyA9IGMoQ2x1c3QuMT0iIzgzYzNiOCIsIENsdXN0LjI9IiMwMDlmZGEiLCBDbHVzdC4zPSIjM2U2OWFjIiwgQ2x1c3QuND0iI2U0NmI2YiIsIENsdXN0LjU9IiNlM2MxNDgiLCBDbHVzdC42PSIjYjdkMTc0IiwgQ2x1c3QuNz0iIzY4YjA0MSIpKQoKcGhlYXRtYXA6OnBoZWF0bWFwKFNtb290aC5jdXJ2ZS5tYXRyaXhbYXMuY2hhcmFjdGVyKFNvcnRlZC5nZW5lLmR5biRHZW5lKSxdLAogICAgICAgICAgICAgICAgICAgc2NhbGUgPSAicm93IiwKICAgICAgICAgICAgICAgICAgIGNsdXN0ZXJfcm93cyA9IEYsCiAgICAgICAgICAgICAgICAgICBjbHVzdGVyX2NvbHMgPSBGLAogICAgICAgICAgICAgICAgICAgZ2Fwc19jb2wgPSBjdW1zdW0oYXMubnVtZXJpYyh0YWJsZShEb21haW5lcy5DbHVzdCREb21haW5lcykpKSwKICAgICAgICAgICAgICAgICAgIGdhcHNfcm93ID0gY3Vtc3VtKGFzLm51bWVyaWModGFibGUoU29ydGVkLmdlbmUuZHluJEdlbmUuQ2x1c3RlcnMpW3Bhc3RlMCgiQ2x1c3QuIixjKDcsMiw2LDMsMSw5LDUsNCw4KSldKSkgLAogICAgICAgICAgICAgICAgICAgI2Fubm90YXRpb25fcm93ID0gU29ydGVkLmdlbmUuZHluICU+JSBkcGx5cjo6c2VsZWN0KEdlbmUuQ2x1c3RlcnMpLAogICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbl9jb2wgPSBEb21haW5lcy5DbHVzdCwKICAgICAgICAgICAgICAgICAgIGFubm90YXRpb25fY29sb3JzID0gYW5uby5jb2xvcnMsCiAgICAgICAgICAgICAgICAgICBzaG93X2NvbG5hbWVzID0gRiwKICAgICAgICAgICAgICAgICAgIHNob3dfcm93bmFtZXMgPSBULAogICAgICAgICAgICAgICAgICAgZm9udHNpemVfcm93ID0gMiwKICAgICAgICAgICAgICAgICAgIGNvbG9yID0gcmV2KGJyZXdlci5wYWwoMTEsIlJkQnUiKSksCiAgICAgICAgICAgICAgICAgICBicmVha3MgPSBzZXEoLTUuMSw1LjEsIGxlbmd0aC5vdXQgPSAxMSksCiAgICAgICAgICAgICAgICAgICBtYWluID0gIkdlbmVzIGV4cHJlc3Npb24gYWxvbmcgRG9yc28tVmVudHJhbCBheGlzIikKYGBgCgoKIyMgQXNzaWduIGRvbWFpbiBpZGVudGl0eQoKV2UgYXNzaWduIGRvbWFpbiBpZGVudGl0eSBiYXNlZCBvbiBjbHVzdGVycycgdHJhbnNjcmlwdGlvbmFsIHByb2ZpbGUgYnkgc2V0dGluZyBib3VuZGFyaWVzIG92ZXIgcHNldWRvLWR2IHNjb3JlCmBgYHtyfQojIFNldCB0aGUgYm91bmRhcnkgb3ZlciBzcGV1ZG90aW1lIHNjb3JlCm5ld19kYXRhJGNsdXN0ZXIgPC0gRG9tYWluZXMuQ2x1c3QkRG9tYWluZXMKSW5mZXJlZC5Eb21haW4uYm91bmRhcnkgPC0gYWdncmVnYXRlKERvcnNvVmVudHJhbC5TY29yZSB+IGNsdXN0ZXIsIG5ld19kYXRhLCBtYXgpICU+JSBwdWxsKERvcnNvVmVudHJhbC5TY29yZSkKCiMgQXNzaWduIGlkZW50aXR5IGJhc2VkIG9uIHRoZSBwb3NpdGlvbiBvZiB0aGUgY2VsbCBvbiB0aGUgcHNldWRvLWR2IGF4aXMKRG9tYWluZS5JZGVudCA8LSBzYXBwbHkoQVAuZGF0YUBtZXRhLmRhdGEkRG9yc29WZW50cmFsLlNjb3JlLAogICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KXsgaWYoeDxJbmZlcmVkLkRvbWFpbi5ib3VuZGFyeVsxXSl7IHggPSAiU3ViLlBhbGxpdW0uMSIKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmKHg+IEluZmVyZWQuRG9tYWluLmJvdW5kYXJ5WzFdICYgeDwgSW5mZXJlZC5Eb21haW4uYm91bmRhcnlbMl0peyB4ID0iU3ViLlBhbGxpdW0uMiIKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmKHg+IEluZmVyZWQuRG9tYWluLmJvdW5kYXJ5WzJdICYgeDwgSW5mZXJlZC5Eb21haW4uYm91bmRhcnlbM10peyB4ID0gIlN1Yi5QYWxsaXVtLjMiIAogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYoeD4gSW5mZXJlZC5Eb21haW4uYm91bmRhcnlbM10gJiB4PCBJbmZlcmVkLkRvbWFpbi5ib3VuZGFyeVs0XSl7IHggPSAiVmVudHJhbC5QYWxsaXVtIgogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYoeD4gSW5mZXJlZC5Eb21haW4uYm91bmRhcnlbNF0gJiB4PCBJbmZlcmVkLkRvbWFpbi5ib3VuZGFyeVs1XSl7IHggPSAibGF0ZXJhbC5QYWxsaXVtLjEiCiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZih4PiBJbmZlcmVkLkRvbWFpbi5ib3VuZGFyeVs2XSl7IHggPSAiRG9yc2FsLlBhbGxpdW0iCiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB4PSJsYXRlcmFsLlBhbGxpdW0uMiJ9KQoKIyBUcmFuc2ZlcnQgdGhlIGlkZW50aXR5IHRvIHRoZSBTZXVyYXQgb2JqZWN0CkFQLmRhdGFAbWV0YS5kYXRhJERvbWFpbmUgPC0gRG9tYWluZS5JZGVudApBUC5kYXRhIDwtIFNldEFsbElkZW50KEFQLmRhdGEsIGlkID0gIkRvbWFpbmUiKQpgYGAKCgpgYGB7ciBmaWcuZGltPWMoNiwgOSksIGZpZy5jYXA9ICJNYW51c2NyaXB0IEZpZy4gNUQifQpQbG90LkdlbmVzLnRyZW5kKEFQLmRhdGEsCiAgICAgICAgICAgICAgICAgZ2VuZXMgPSBjKCJHc3gyIiwgIkRieDEiLCAiR20yOTI2MCIsICJUZmFwMmMiLCAiRW14MSIsICJMcnJuMSIpLAogICAgICAgICAgICAgICAgIFVzZS5zY2FsZS5kYXRhID0gRikKYGBgCgpgYGB7ciBmaWcuZGltPWMoNS4zLCA0KX0KRGltUGxvdChBUC5kYXRhLAogICAgICAgICBncm91cC5ieSA9ICJEb21haW5lIiwKICAgICAgICAgcmVkdWN0aW9uLnVzZSA9ICJzcHJpbmciLAogICAgICAgICBkaW0uMSA9IDEsCiAgICAgICAgIGRpbS4yID0gMiwKICAgICAgICAgZG8ubGFiZWw9RiwKICAgICAgICAgbGFiZWwuc2l6ZSA9IDQsCiAgICAgICAgIG5vLmxlZ2VuZCA9IEYsCiAgICAgICAgIGNvbHMudXNlID0gdG9sb3dlcihjKCIjNjhCMDQxIiwgIiNFM0MxNDgiLCAiI0I3RDE3NCIsICIjODNDM0I4IiwgIiMwMDlGREEiLCAiIzNFNjlBQyIsICIjRTQ2QjZCIikpCiAgICAgICAgICkKYGBgCgojIFBsb3QgRmlndXJlIDVCCgpgYGB7cn0KI2xvYWQgZnVsbCBkYXRhc2V0CkFsbGNlbGxzLmRhdGEgPC0gcmVhZFJEUygiLi9RQy5maWx0ZXJlZC5jZWxscy5SRFMiKQoKI1RyYW5zZmVyIHRoZSBpZGVudGl0aWVzClJlbmFtZS5DbHVzdCA8LSAgZnVuY3Rpb24oQ2x1c3RkYXRhLCBSYXdRQ2RhdGEpIHsKICB1bkNsdXN0ZXJlZC5jZWxscyA8LSBSYXdRQ2RhdGFAbWV0YS5kYXRhJEJhcmNvZGVzCiAgUmF3UUNkYXRhIDwtIFNldElkZW50KFJhd1FDZGF0YSwgY2VsbHMudXNlID0gdW5DbHVzdGVyZWQuY2VsbHMsIGlkZW50LnVzZSA9ICJBbGwuVW5jbHVzdGVyZWQuQ2VsbHMiKQogIAogIGZvcihpIGluIHVuaXF1ZShDbHVzdGRhdGFAbWV0YS5kYXRhJERvbWFpbmUpKXsKICBOZXcuaWRlbnQgPC0gaQogIEJhcmNvZGVzIDwtIHJvd25hbWVzKHN1YnNldChDbHVzdGRhdGFAbWV0YS5kYXRhLCBDbHVzdGRhdGFAbWV0YS5kYXRhJERvbWFpbmUgPT0gaSkpCiAgcHJpbnQocGFzdGUwKCJDbHVzdGVyXyIsaSwiOiAiLGxlbmd0aChCYXJjb2RlcyksICIgQ2VsbHMiKSkKICBCYXJjb2RlcyA8LSBCYXJjb2Rlc1tCYXJjb2RlcyAlaW4lIHJvd25hbWVzKFJhd1FDZGF0YUBtZXRhLmRhdGEpXQogIFJhd1FDZGF0YSA8LSBTZXRJZGVudChSYXdRQ2RhdGEsIGNlbGxzLnVzZSA9IEJhcmNvZGVzICxpZGVudC51c2UgPSBwYXN0ZTAoIkFQLiIsaSkpCiAgfQogIHJldHVybihSYXdRQ2RhdGEpCn0KCkFsbGNlbGxzLmRhdGEgPC0gUmVuYW1lLkNsdXN0KENsdXN0ZGF0YSA9IEFQLmRhdGEsIFJhd1FDZGF0YSA9IEFsbGNlbGxzLmRhdGEpCmBgYAoKYGBge3IgZmlnLmRpbT1jKDUuMywgNCksICwgZmlnLmNhcD0gIk1hbnVzY3JpcHQgRmlnLiA1QiJ9CmNvbG9ycyA8LSAgYygiIzk2OTY5NiIsdG9sb3dlcihjKCIjNjhCMDQxIiwgIiNFM0MxNDgiLCAiI0I3RDE3NCIsICIjODNDM0I4IiwgIiMwMDlGREEiLCAiIzNFNjlBQyIsICIjRTQ2QjZCIikpKQoKRGltUGxvdChBbGxjZWxscy5kYXRhLAogICAgICAgIHJlZHVjdGlvbi51c2UgPSAic3ByaW5nIiwgCiAgICAgICAgZGltLjEgPSAxLAogICAgICAgIGRpbS4yID0gMiwKICAgICAgICBkby5sYWJlbD1ULAogICAgICAgIGxhYmVsLnNpemUgPSAyLAogICAgICAgIG5vLmxlZ2VuZCA9IFQsCiAgICAgICAgY29scy51c2UgPSBjb2xvcnMpCmBgYAoKYGBge3J9CnJtKGxpc3QgPSBscygpWyFscygpICVpbiUgYygiQVAuZGF0YSIpXSkKYGBgCgojIFBsb3QgdGhlIHJlcHJlc2VudGF0aXZlIGdlbmUgb2YgdGhlIEZpZ3VyZSBTNgoKYGBge3J9CiMgTG9hZCBjdXN0b20gcGxvdHRpbmcgZnVuY3Rpb25zCnNvdXJjZSgiLi9mdW5jdGlvbnMvR2VuZXNUcmVuZFBsb3RzLlIiKQpgYGAKCiMjIENsdXN0ZXIgNgoKYGBge3IgZmlnLmRpbT1jKDYsIDkpLCBmaWcuY2FwPSAiTWFudXNjcmlwdCBGaWcuUzZBIn0KUGxvdC5HZW5lcy50cmVuZChBUC5kYXRhLAogICAgICAgICAgICAgICAgIGdlbmVzID0gYygiRGx4MSIsICJBbm8xIiwgIkRseDIiLCAiT2xpZzIiKSwKICAgICAgICAgICAgICAgICBVc2Uuc2NhbGUuZGF0YSA9IEYpCmBgYAoKIyMgQ2x1c3RlciAyCgpgYGB7ciBmaWcuZGltPWMoNiwgOSksIGZpZy5jYXA9ICJNYW51c2NyaXB0IEZpZy5TNkIifQpQbG90LkdlbmVzLnRyZW5kKEFQLmRhdGEsCiAgICAgICAgICAgICAgICAgZ2VuZXMgPSBjKCJPdHgyIiwgIlpidGIyMCIsICJTaXgzIiwgIkFzY2wxIiksCiAgICAgICAgICAgICAgICAgVXNlLnNjYWxlLmRhdGEgPSBGKQpgYGAKCiMjIENsdXN0ZXIgMwoKYGBge3IgZmlnLmRpbT1jKDYsIDkpLCBmaWcuY2FwPSAiTWFudXNjcmlwdCBGaWcuUzZDIn0KUGxvdC5HZW5lcy50cmVuZChBUC5kYXRhLAogICAgICAgICAgICAgICAgIGdlbmVzID0gYygiTWVpczEiLCAiUm9yYiIsICJFcGhhMyIpLAogICAgICAgICAgICAgICAgIFVzZS5zY2FsZS5kYXRhID0gRikKYGBgCgojIyBDbHVzdGVyIDEKCmBgYHtyIGZpZy5kaW09Yyg2LCA5KSwgZmlnLmNhcD0gIk1hbnVzY3JpcHQgRmlnLlM2RCJ9ClBsb3QuR2VuZXMudHJlbmQoQVAuZGF0YSwKICAgICAgICAgICAgICAgICBnZW5lcyA9IGMoIlNmcnAyIiwgIkV2YTFjIiwgIlNlbWE1YSIsICJGYXQ0IiksCiAgICAgICAgICAgICAgICAgVXNlLnNjYWxlLmRhdGEgPSBGKQpgYGAKCiMjIENsdXN0ZXIgOQoKYGBge3IgZmlnLmRpbT1jKDYsIDkpLCBmaWcuY2FwPSAiTWFudXNjcmlwdCBGaWcuUzZFIn0KUGxvdC5HZW5lcy50cmVuZChBUC5kYXRhLAogICAgICAgICAgICAgICAgIGdlbmVzID0gYygiRG1ydGEyIiwiTHlwZDYiLCAiUGF4NiIsICJEbXJ0YTEiKSwKICAgICAgICAgICAgICAgICBVc2Uuc2NhbGUuZGF0YSA9IEYpCmBgYAoKIyMgQ2x1c3RlciA1ID8KCmBgYHtyIGZpZy5kaW09Yyg2LCA5KSwgZmlnLmNhcD0gIk1hbnVzY3JpcHQgRmlnLlM2RiJ9ClBsb3QuR2VuZXMudHJlbmQoQVAuZGF0YSwKICAgICAgICAgICAgICAgICBnZW5lcyA9IGMoIkVteDEiLCAiQXJ4IiwgIkxtbzMiKSwKICAgICAgICAgICAgICAgICBVc2Uuc2NhbGUuZGF0YSA9IEYpCmBgYAoKIyMgQ2x1c3RlciA5CgpgYGB7ciBmaWcuZGltPWMoNiwgOSksIGZpZy5jYXA9ICJNYW51c2NyaXB0IEZpZy5TNkcifQpQbG90LkdlbmVzLnRyZW5kKEFQLmRhdGEsCiAgICAgICAgICAgICAgICAgZ2VuZXMgPSBjKCJGZXpmMiIsICJFbXgyIiwgIlNwOCIpLAogICAgICAgICAgICAgICAgIFVzZS5zY2FsZS5kYXRhID0gRikKYGBgCgojIFRyYW5zZmVydCB0aGVzZSBpZGVudCBvbiB0aGUgZnVsbCBkYXRhc2V0IChNYW51c2NyaXB0IEZpZy4gMkEpCgpgYGB7cn0KI2xvYWQgZnVsbCBkYXRhc2V0CkFsbGNlbGxzLmRhdGEgPC0gcmVhZFJEUygiLi9DbHVzdGVyZWQuY2VsbHMuUkRTIikKCiNUcmFuc2ZlciB0aGUgaWRlbnRpdGllcwpSZW5hbWUuQ2x1c3QgPC0gIGZ1bmN0aW9uKENsdXN0ZGF0YSwgUmF3UUNkYXRhKSB7CiAgZm9yKGkgaW4gdW5pcXVlKENsdXN0ZGF0YUBtZXRhLmRhdGEkRG9tYWluZSkpewogICAgTmV3LmlkZW50IDwtIGkKICAgIEJhcmNvZGVzIDwtIHJvd25hbWVzKHN1YnNldChDbHVzdGRhdGFAbWV0YS5kYXRhLCBDbHVzdGRhdGFAbWV0YS5kYXRhJERvbWFpbmUgPT0gaSkpCiAgICBwcmludChwYXN0ZTAoIkNsdXN0ZXJfIixpLCI6ICIsbGVuZ3RoKEJhcmNvZGVzKSwgIiBDZWxscyIpKQogICAgQmFyY29kZXMgPC0gQmFyY29kZXNbQmFyY29kZXMgJWluJSByb3duYW1lcyhSYXdRQ2RhdGFAbWV0YS5kYXRhKV0KICAgIFJhd1FDZGF0YSA8LSBTZXRJZGVudChSYXdRQ2RhdGEsIGNlbGxzLnVzZSA9IEJhcmNvZGVzICxpZGVudC51c2UgPSBwYXN0ZTAoIkFQLiIsaSkpCiAgfQogIHJldHVybihSYXdRQ2RhdGEpCn0KCkFsbGNlbGxzLmRhdGEgPC0gUmVuYW1lLkNsdXN0KENsdXN0ZGF0YSA9IEFQLmRhdGEsIFJhd1FDZGF0YSA9IEFsbGNlbGxzLmRhdGEpCmBgYAoKYGBge3IgZmlnLmRpbT1jKDgsIDYpLCBmaWcuY2FwPSAiTWFudXNjcmlwdCBGaWcuIDJBIn0KY29sb3JzMiA8LSAgYygiIzk2OTY5NiIsCiAgICAgICAgICAgICAgdG9sb3dlcihjKCIjNjhCMDQxIiwgIiNFM0MxNDgiLCAiI0I3RDE3NCIsICIjODNDM0I4IiwgIiMwMDlGREEiLCAiIzNFNjlBQyIsICIjRTQ2QjZCIikpLAogICAgICAgICAgICAgICIjZWM3NTZkIiwgIiNjNzczYTciLCAiIzcyOTNjOCIsICIjYjc5ZjBiIiwgIiMzY2E3M2YiLCIjMzFiNmJkIiwKICAgICAgICAgICAgICAiI2ViY2IyZSIsICIjOWVjMjJmIiwgIiNhOTk2MWIiLCAiI2NjM2ExYiIsICIjY2M4Nzc4IiAsICIjZDE0YzhkIiwgIiM0Y2FiZGMiLCAiIzVhYjc5MyIsICIjZTc4MjNhIiwiI2U2YmI5YiIsICIjMDQ2YzlhIiwgIiM0Nzg0YTIiICwgIiM0OTkwYzkiKQoKRGltUGxvdChBbGxjZWxscy5kYXRhLAogICAgICAgIHJlZHVjdGlvbi51c2UgPSAic3ByaW5nIiwgCiAgICAgICAgZGltLjEgPSAxLAogICAgICAgIGRpbS4yID0gMiwKICAgICAgICBkby5sYWJlbD1ULAogICAgICAgIGxhYmVsLnNpemUgPSAyLAogICAgICAgIG5vLmxlZ2VuZCA9IFQsCiAgICAgICAgY29scy51c2UgPSBjb2xvcnMyKQpgYGAKCmBgYHtyfQpBbGxjZWxscy5kYXRhIDwtIFN0YXNoSWRlbnQoQWxsY2VsbHMuZGF0YSwgc2F2ZS5uYW1lID0gIkNsdXN0ZXIuaWRlbnQiKQpzYXZlUkRTKEFsbGNlbGxzLmRhdGEsICIuL0NsdXN0ZXJlZC5jZWxscy5SRFMiKQpybShsaXN0ID0gbHMoKVshbHMoKSAlaW4lIGMoIkFsbGNlbGxzLmRhdGEiKV0pCmBgYAoKIyBTZXNzaW9uIEluZm8KYGBge3J9CiNkYXRlCmZvcm1hdChTeXMudGltZSgpLCAiJWQgJUIsICVZLCAlSCwlTSIpCgojUGFja2FnZXMgdXNlZApzZXNzaW9uSW5mbygpCmBgYA==